package com.mti.monitor.service;

import com.mti.monitor.bean.model.SysMonitorConfig;
import com.mti.monitor.bean.model.SysMonitorErrorLog;
import com.mti.monitor.config.properties.Constants;
import com.mti.monitor.mapper.SysMonitorConfigMapper;
import com.mti.monitor.mapper.SysMonitorErrorLogMapper;
import com.mti.monitor.util.AESUtil;
import com.mti.monitor.util.SSHUtil;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;


@Service
@Log4j2
public class ServerMonitorService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SysMonitorConfigMapper sysMonitorConfigMapper;
    @Autowired
    private SysMonitorErrorLogMapper sysMonitorErrorLogMapper;
    @Autowired
    private MessageService messageService;

    /**
     * 监控服务器心跳情况
     */
    public void monitorServerHeart(String monitorId) {
        SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_TIME_FORMAT);
        SysMonitorConfig config = sysMonitorConfigMapper.selectById(monitorId.replaceAll( Constants.TASK_NAME_EXT,""));
        if(!config.getUseYn()){
            return;
        }
        try {
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(config.getSystemUrl(), String.class);
            if (responseEntity.getStatusCode().value() != HttpStatus.OK.value()) {
                throw new Exception("服务异常");
            }
            log.info("服务:{}于{} 心跳检查正常", config.getSystemName(), sdf.format(new Date()));
        } catch (Exception exception) {
            log.warn("服务:{}于{} 心跳检查失败", config.getSystemName(), sdf.format(new Date()));
            //获取上一条异常信息
            SysMonitorErrorLog errorLog = sysMonitorErrorLogMapper.queryLastRecord(monitorId);
            //判断时间间隔，如果时间间隔大于配置时间间隔，则认为是新的异常记录，记录数量为1
            int failCount = 1;
            //如果时间间隔小于配置，则认为是累计发现的异常记录，记录数量为上一次异常信息的数量+1
            if (errorLog != null) {
                String[] intervalTime = config.getIntervalTime().split(" ");
                Date lastRecordDate = errorLog.getExecuteTime();
                long currentIntervalTime = (new Date()).getTime() - lastRecordDate.getTime();
                //因为服务器上可能存在一定的时间、执行顺序等误差，所以调整时间增加10秒
                long allowIntervalTime = 10 * 1000;
                if (intervalTime[1].equals("day")) {
                    allowIntervalTime += Long.parseLong(intervalTime[0]) * 24 * 60 * 60 * 1000;
                } else if (intervalTime[1].equals("hour")) {
                    allowIntervalTime += Long.parseLong(intervalTime[0]) * 60 * 60 * 1000;
                } else if (intervalTime[1].equals("min")) {
                    allowIntervalTime += Long.parseLong(intervalTime[0]) * 60 * 1000;
                }


                if (allowIntervalTime >= currentIntervalTime) {
                    failCount = errorLog.getFailCount() + 1;
                }
            }
            boolean sendMessageYn = false;
            //如果累计记录数量等于配置数量，则发送短信
            if(failCount == config.getAllowErrorCount().intValue() + 1){
                sendMessageYn = true;
                messageService.sendAlarmMessage(config.getPhoneNumbers(),config.getMessageContent(),config.getMessageChannel());
            }
            //添加本次异常记录
            SysMonitorErrorLog currentLog = new SysMonitorErrorLog();
            currentLog.setLogId(UUID.randomUUID().toString().replaceAll("-",""));
            currentLog.setId(monitorId);
            currentLog.setExecuteTime(new Date());
            currentLog.setFailCount(failCount);
            currentLog.setSendMessageYn(sendMessageYn);
            if(sendMessageYn) {
                currentLog.setMessageContent(config.getMessageContent());
                currentLog.setPhoneNumbers(config.getPhoneNumbers());
            }
            sysMonitorErrorLogMapper.insert(currentLog);
        }

    }


    @SneakyThrows
    public void restartServer(String monitorId){
        SysMonitorConfig config = sysMonitorConfigMapper.selectById(monitorId.replaceAll( Constants.TASK_NAME_EXT,""));
        String sshPwd = AESUtil.decode(AESUtil.DEFAULT_SECRET_KEY, config.getSshPwd());
        SSHUtil sshUtil = new SSHUtil(config.getSshUser(), sshPwd, config.getSshIp(), config.getSshPort());
        sshUtil.connect();
        sshUtil.executeCmd("sh " + config.getRestartFilePath());
        sshUtil.disconnect();
    }
}
